/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.risk.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.koron.audit.domain.Audit;
import com.koron.audit.management.FlowManagement;
import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.web.Util;
import com.koron.hazardsource.domain.IndicationItems;
import com.koron.hazardsource.domain.IndicationType;
import com.koron.hazardsource.service.api.IndicationTypeService;
import com.koron.hazardsource.util.Immutable;
import com.koron.hazardsource.util.RiskLECDesc;
import com.koron.hazardsource.util.RiskLevelDesc;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.bean.SourceQueryBean;
import com.koron.risk.domain.LocalHazardSource;
import com.koron.risk.domain.LocalRisk;
import com.koron.risk.mapper.CorpManagementMapper;
import com.koron.risk.mapper.LocalHazardSourceMapper;
import com.koron.risk.mapper.LocalRiskMapper;
import com.koron.risk.service.api.LocalHazardSourceService;
import com.koron.risk.util.BusinessCode;
import com.koron.system.domain.DictData;
import com.koron.system.service.api.DictDataService;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

@Service
@PropertySource({"classpath:flow.properties"})
public class LocalHazardSourceServiceImpl implements LocalHazardSourceService {

    private final static Logger logger= LoggerFactory.getLogger(LocalHazardSourceServiceImpl.class);
    @Autowired
    private Util util;

    @Autowired
    private DictDataService dataService;

    @Autowired
    private FlowManagement flowManagement;

    @Value("${lhs_add_flow_template_key}")
    private String addTemplateKey;
    @Value("${lhs_import_flow_template_key}")
    private String importTemplateKey;

    @Value("${risk_danger_setCode}")
    private String riskDangerSetCode;

//	@Value("${lhs_flow_template_key_import}")
//	private String templateKeyImport;

    @Autowired
    private CorpManagementServiceImpl corpManagementService;

    @SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
    @Override
    public MessageBean<?> list(SourceQueryBean queryBean) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, DataBean.class);
        Integer totalPage = null;
        Integer totalNumber = null;
        Integer start = null;
        Integer end = null;
        Integer page = queryBean.getPage();
        Integer pageSize = queryBean.getPageSize();
        if (null != page && pageSize != null) {
            if (page > 0 && pageSize > 0) {
            } else {
                //第一页 10条数据
                page = 1;
                pageSize = 10;
            }
            start = (page <= 1) ? 0 : (page - 1) * pageSize;
            end = pageSize;
        }
        queryBean.setStart(start);
        queryBean.setEnd(end);
        queryBean.setTableName("local_hazard_source");
        if (null != queryBean.getRiskLevelStart()) {
            if (queryBean.getRiskLevelStart() == 1) {
                queryBean.setLevelStart(1);
            } else if (queryBean.getRiskLevelStart() == 5) {
                queryBean.setLevelStart(70);
            } else if (queryBean.getRiskLevelStart() == 10) {
                queryBean.setLevelStart(160);
            } else if (queryBean.getRiskLevelStart() == 17) {
                queryBean.setLevelStart(320);
            }
        }
        if (null != queryBean.getRiskLevelEnd()) {
            if (queryBean.getRiskLevelEnd() == 4) {
                queryBean.setLevelEnd(70);
            } else if (queryBean.getRiskLevelEnd() == 9) {
                queryBean.setLevelEnd(160);
            } else if (queryBean.getRiskLevelEnd() == 16) {
                queryBean.setLevelEnd(320);
            } else if (queryBean.getRiskLevelEnd() == 25) {
                queryBean.setLevelEnd(10000);
            }
        }
        try (SessionFactory factory = new SessionFactory();) {
            String deptCodes = util.getDeptCodes(queryBean.getCorpCode());
            queryBean.setCorpCode(deptCodes);
            totalNumber = factory.getMapper(LocalHazardSourceMapper.class).count(queryBean);
            if (start != null && end != null) {
                totalPage = (totalNumber + pageSize - 1) / pageSize;
            } else {
                totalPage = 1;
                page = totalPage;
                pageSize = totalNumber;
            }
            DataBean data = new DataBean();
            data.setList(queryList(queryBean));
            data.setPageNo(page);
            data.setPageSize(pageSize);
            data.setTotalNumber(totalNumber);
            data.setTotalPage(totalPage);
            msg.setData(data);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<?> getDetails(String tableName, String riskName, String id) {
        MessageBean<LocalHazardSource> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, LocalHazardSource.class);
        if (StringUtils.isEmpty(id)) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        try (SessionFactory factory = new SessionFactory();) {
            LocalHazardSource bean = factory.getMapper(LocalHazardSourceMapper.class).getDetails(tableName, id);
            if (bean == null) {
                return msg;
            }
            bean.setRisks(factory.getMapper(LocalRiskMapper.class).queryBySourceId(riskName, id));
            msg.setData(bean);
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings({"deprecation", "unchecked", "rawtypes"})
    @Override
    public MessageBean<?> discard(List<String> idList, StaffBean user, String title, String note, String approvalCode) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, void.class);
        SessionFactory factory = new SessionFactory();
        try {
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            List<LocalHazardSource> lhsList = lhsMapper.queryByIdList("local_hazard_source", idList);
            List<LocalRisk> lrList = new ArrayList<LocalRisk>();
            idList = new ArrayList<String>();
            for (LocalHazardSource lhs : lhsList) {
                List<LocalRisk> temp = lrMapper.queryBySourceId("local_risk", lhs.getId());
                String id = DefaultIdGenerator.getInstance().generateLongId();
                lhs.setId(id);
                lhs.setState(0);
                lhs.setFstatusflag(0);
                for (LocalRisk lr : temp) {
                    lr.setId(DefaultIdGenerator.getInstance().generateLongId());
                    lr.setLocalHazardId(id);
                }
                lrList.addAll(temp);
                idList.add(id);
            }
            //保存到历史表
            lhsMapper.batchInsert("local_hazard_source_history", lhsList);
            lrMapper.batchInsert("local_risk_history", lrList);
            String corpCode = lhsList.get(0).getCorpCode();
            String tk = addTemplateKey;
            //启动流程
            Audit audit = new Audit(title, note, user.getName(), new Date());
            audit.setId(DefaultIdGenerator.getInstance().generateLongId());
            audit.setTitle(title);
            audit.setDescription(note);
            audit.setInitiatorCode(user.getCode());
            audit.setTarget(LocalHazardSource.class.getName());
            audit.setTemplateKey(tk);
            audit.setOperation(2); //废弃
            audit.setState(1);
            audit.setFlowType(1);
            audit.setFlowName(Immutable.DISCARD_LOCAL_HAZARD_SOURCE);
            audit.setBusinessIds(new Gson().toJson(idList));
            audit.setInitiatorAccount(user.getUserid());
            audit.setSetCode(riskDangerSetCode);
            audit.setCorpCode(corpCode);

            Map map = new HashMap<>();
            map.put("approvalCode", approvalCode);
            if (flowManagement.initFlow(user, audit, map)) {
                factory.close();
            } else {
                msg.setCode(BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                factory.close(false);
            }
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }
        return msg;
    }

    /**
     * 合并单元格处理,获取合并行
     *
     * @param sheet
     * @return List<CellRangeAddress>
     */
    public List<CellRangeAddress> getCombineCell(XSSFSheet sheet) {
        List<CellRangeAddress> list = new ArrayList<CellRangeAddress>();
        // 获得一个 sheet 中合并单元格的数量
        int sheetmergerCount = sheet.getNumMergedRegions();
        // 遍历所有的合并单元格
        for (int i = 0; i < sheetmergerCount; i++) {
            // 获得合并单元格保存进list中
            CellRangeAddress ca = sheet.getMergedRegion(i);
            list.add(ca);
        }
        return list;
    }

    private CellRangeAddress getCellRange(List<CellRangeAddress> listCombineCell, XSSFCell cell) {
        if (null == cell) {
            return null;
        }
        int firstC = 0, lastC = 0, firstR = 0, lastR = 0;
        for (CellRangeAddress ca : listCombineCell) {
            // 获得合并单元格的起始行, 结束行, 起始列, 结束列
            firstC = ca.getFirstColumn();
            lastC = ca.getLastColumn();
            firstR = ca.getFirstRow();
            lastR = ca.getLastRow();
            if (cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR) {
                if (cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC) {
                    return ca;
                }
            }
        }
        return null;
    }

    /**
     * 获取单元格的值
     *
     * @param cell
     * @return
     */
    @SuppressWarnings("deprecation")
    public String getCellValue(XSSFCell cell) {
        if (cell == null)
            return "";
        if (cell.getCellTypeEnum() == CellType.STRING) {
            return cell.getStringCellValue();
        } else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellTypeEnum() == CellType.FORMULA) {
            return cell.getCellFormula();
        } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
            return String.valueOf(cell.getNumericCellValue());
        } else {
            return "";
        }
    }

    @SuppressWarnings("deprecation")
    public LocalHazardSource queryByCode(String tableName, String code) {
        LocalHazardSource lhs = new LocalHazardSource();
        try (SessionFactory factory = new SessionFactory();) {
            lhs = factory.getMapper(LocalHazardSourceMapper.class).queryByCode(tableName, code);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return lhs;
    }

    @Autowired
    private IndicationTypeService indicationTypeService;

    private LocalHazardSource parseHazardSource(Map rowMap, StaffBean user, StringBuffer sb, Integer total) {
        LocalHazardSource lhs = new LocalHazardSource();
        lhs.setFitAllBusiness(true);
        XSSFRow row = (XSSFRow) rowMap.get("row");
        Integer rowNum = (Integer) rowMap.get("rowNum");
        String region = getCellValue(row.getCell(0));
        String sourceName = getCellValue(row.getCell(2));
        if (!StringUtils.isEmpty(sourceName)) {
            total++;
        } else {
            return null;
        }
        String fitAll = getCellValue(row.getCell(3));
        if (StringUtils.isEmpty(fitAll)) {
            fitAll = "n";
        }
        if (fitAll.equalsIgnoreCase("否") || fitAll.equalsIgnoreCase("n") || fitAll.equalsIgnoreCase("no")) {
            lhs.setFitAllBusiness(false);
            String businessTypeName = getCellValue(row.getCell(4));
            if (StringUtils.isEmpty(businessTypeName)) {
                sb.append("第" + rowNum + "行,业务类型为空，该行未导入;\n");
                return null;
            }
            DictData businessTypeItem = dataService.matchDictData("业态", businessTypeName);
            if (businessTypeItem == null) {
                sb.append("第" + rowNum + "行,业务类型未在系统中找到匹配项，该行未导入;\n");
                return null;
            }
            lhs.setBusinessTypeId(businessTypeItem.getId());
            lhs.setBusinessTypeName(businessTypeName);
        }
        String hazardTypeName = getCellValue(row.getCell(5));
        if (StringUtils.isEmpty(hazardTypeName)) {
            sb.append("第" + rowNum + "行,危险源类型为空，该行未导入;\n");
            return null;
        }
        DictData hazardTypeItem = dataService.matchDictData("危险源类型", hazardTypeName);
        if (hazardTypeItem == null) {
            sb.append("第" + rowNum + "行,危险源类型未在系统中找到匹配项，该行未导入;\n");
            return null;
        }

        IndicationType indicationType = indicationTypeService.fetchForKey("hazardsource_level_type");
        String indicationLevelName = getCellValue(row.getCell(6));
        String identificationType = getCellValue(row.getCell(7));
        if (StringUtils.isEmpty(indicationLevelName)) {
            lhs.setIndicationLevelId(indicationType.getIndicationItems().get(0).getId());
        } else {
            boolean flag = false;
            for (IndicationItems indication : indicationType.getIndicationItems()) {
                if (indication.getName().equalsIgnoreCase(indicationLevelName)) {
                    lhs.setIndicationLevelId(indication.getId());
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                lhs.setIndicationLevelId(indicationType.getIndicationItems().get(0).getId());
            }
        }
        lhs.setRegion(region);
        lhs.setName(sourceName);
        lhs.setRowNo(rowNum);
        lhs.setHazardTypeId(hazardTypeItem.getId());
        lhs.setHazardTypeName(hazardTypeName);
        lhs.setIdentificationType(identificationType);
        // 导入的code
        lhs.setCode(getCellValue(row.getCell(1)));
        return lhs;
    }

    // 单个危险源和多个风险
    private String parseRows(List<Map> rows, Map<LocalHazardSource, List<LocalRisk>> map, StaffBean user, StringBuffer description, Integer total) throws Exception {
        LocalHazardSource lhs = new LocalHazardSource();
        List<LocalRisk> riskList = new ArrayList<>();
        for (int i = 0; i < rows.size(); i++) {
            if (i == 0) {
                lhs = parseHazardSource(rows.get(i), user, description, total);
                if (lhs == null) {
                    return null;
                }
            }
            LocalRisk risk = parseRisk(lhs.getIdentificationType(), rows.get(i), description);
            if (risk != null) {
                riskList.add(risk);
            }
        }
        if (!riskList.isEmpty()) {
            map.put(lhs, riskList);
        }
        return description.toString();
    }

    private LocalRisk parseRisk(String identificationType, Map rowMap, StringBuffer sb) {
        XSSFRow row = (XSSFRow) rowMap.get("row");
        Integer rowNum = (Integer) rowMap.get("rowNum");
        String accidentTypeName = getCellValue(row.getCell(8));
        if (StringUtils.isEmpty(accidentTypeName)) {
            sb.append("第" + rowNum + "行,事故类型为空，该行未导入;");
        }
        DictData accidentTypeItem = dataService.matchDictData("事故类型", accidentTypeName);
        if (accidentTypeItem == null) {
            sb.append("第" + rowNum + "行,事故类型未在系统中找到匹配项，该行未导入;");
            return null;
        }
        LocalRisk lr = new LocalRisk();
        lr.setRiskInfo(getCellValue(row.getCell(9)));
        lr.setRiskReason(getCellValue(row.getCell(10)));
        lr.setAccidentTypeId(accidentTypeItem.getId());
        if ("LS".equals(identificationType)) {
            if (!StringUtils.isEmpty(getCellValue(row.getCell(11)))) {
                lr.setPossibility((int) Math.round(Double.parseDouble(getCellValue(row.getCell(11)))));
            }
            if (!StringUtils.isEmpty(getCellValue(row.getCell(12)))) {
                lr.setSeverity((int) Math.round(Double.parseDouble(getCellValue(row.getCell(12)))));
            }
            lr.setPrecaution(getCellValue(row.getCell(15)));
            if (!StringUtils.isEmpty(getCellValue(row.getCell(16)))) {
                Integer residuePossibility = (int) Math.round(Double.parseDouble(getCellValue(row.getCell(16))));
                lr.setResiduePossibility(residuePossibility);
            }
            if (!StringUtils.isEmpty(getCellValue(row.getCell(17)))) {
                Integer residueSeverity = (int) Math.round(Double.parseDouble(getCellValue(row.getCell(17))));
                lr.setResidueSeverity(residueSeverity);
            }
        } else {
            BigDecimal occurencePossibility = new BigDecimal(Double.parseDouble(getCellValue(row.getCell(20))) + "");
            BigDecimal frequently = new BigDecimal(Double.parseDouble(getCellValue(row.getCell(21))) + "");
            BigDecimal consequence = new BigDecimal(Double.parseDouble(getCellValue(row.getCell(22))) + "");
            lr.setOccurencePossibility(occurencePossibility);
            lr.setFrequently(frequently);
            lr.setConsequence(consequence);
        }
        return lr;
    }

    @SuppressWarnings("resource")
    @Override
    public MessageBean<?> importFromExcel(StaffBean user, MultipartFile file, String title,
                                          String note, String corpCode, String approvalCode) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, void.class);
        if (file == null) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        StringBuffer description = new StringBuffer();
        Integer total = 0;
        try {
            //上传文件
            String fileName = file.getOriginalFilename();
            //文件上传的路径
            String filePath = clientWrapper.uploadFile(file) + "#" + fileName;
            InputStream inputStream = file.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (null != sheet) {
                Map<LocalHazardSource, List<LocalRisk>> map = new HashMap<>();
                List<CellRangeAddress> combineCell = getCombineCell(sheet);
                int rowsNumm = sheet.getPhysicalNumberOfRows();
                for (int i = 4; i < rowsNumm; ) {
                    XSSFRow row = sheet.getRow(i);
                    if (null == row) {
                        i++;
                        continue;
                    }
                    // 合并了多行，取合并后单元格范围信息
                    CellRangeAddress cellRange = getCellRange(combineCell, row.getCell(1));
                    int lastRow = i;
                    if (cellRange != null) {
                        lastRow = cellRange.getLastRow();
                    }
                    List<Map> rows = new ArrayList<>();
                    while (lastRow >= i) {
                        Map rowMap = new HashMap();
                        rowMap.put("row", sheet.getRow(i));
                        rowMap.put("rowNum", i + 1);
                        rows.add(rowMap);
                        i++;
                    }
                    parseRows(rows, map, user, description, total);
                }
                msg = importSubmit(filePath, user, map, title, note, corpCode, approvalCode);
                Integer success = 0;
                if (null != msg.getData()) {
                    List<String> data = (List<String>) msg.getData();
                    success = data.size();
                }
                if (msg.getCode() == 0) {
                    msg.setDescription("导入情况，成功导入" + success + "条" + "\n" + description);
                } else {
                    msg.setDescription(msg.getDescription() + description);
                }
            }
            return msg;
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription("导入失败!" + description);
            return msg;
        }
    }

    @Autowired
    private FastDFSClientWrapper clientWrapper;

    @SuppressWarnings({"unchecked", "rawtypes"})
    private MessageBean importSubmit(String filePath, StaffBean user, Map<LocalHazardSource, List<LocalRisk>> map, String title, String note, String corpCode, String approvalCode) {
        MessageBean<?> msg = new MessageBean<>();
        List<LocalHazardSource> beanList = new ArrayList<>();
        try {
            //到目前为止危险源和风险等数据都是excel表中原始数据，没有添加其他属性，下面的处理中将会添加
            for (Map.Entry<LocalHazardSource, List<LocalRisk>> entry : map.entrySet()) {
                LocalHazardSource lhs = entry.getKey();
                List<LocalRisk> riskList = entry.getValue();
                if (riskList.isEmpty()) {
                    continue;
                }
                lhs.setRisks(riskList);
                lhs.setCorpCode(corpCode);
                beanList.add(lhs);
            }
            //保存草稿
            msg = saveDraft(beanList, user);
            List<String> idList = new ArrayList<String>();
            if (msg.getData() != null) {
                idList = (List<String>) msg.getData();
            } else {
                return msg;
            }
            if (null != idList && idList.size() > 0) {
                String tk = importTemplateKey;
                //启动流程
                Audit audit = new Audit(title, note, user.getName(), new Date());
                audit.setId(DefaultIdGenerator.getInstance().generateLongId());
                audit.setTitle(title);
                audit.setDescription(note);
                audit.setInitiatorCode(user.getCode());
                audit.setTarget(LocalHazardSource.class.getName());
                audit.setTemplateKey(tk);
                audit.setOperation(1); //编辑
                audit.setState(1);
                audit.setFlowType(1);
                audit.setFlowName(Immutable.ADD_LOCAL_HAZARD_SOURCE);
                audit.setBusinessIds(new Gson().toJson(idList));
                audit.setAttachment(filePath);
                audit.setCorpCode(corpCode);
                audit.setInitiatorAccount(user.getUserid());
                audit.setSetCode(riskDangerSetCode);
                Map adMap = new HashMap<>();
                if (StringUtils.isEmpty(approvalCode)) {
                    approvalCode = user.getUserid();
                }
                adMap.put("approvalCode", approvalCode);
                if (!flowManagement.initFlow(user, audit, adMap)) {
                    delete(idList);
                    msg.setCode(BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                    return msg;
                }
                updateFstatusflag(idList, 1);  //审批中
            }
            msg.setDescription("提交成功");
            return msg;
        } catch (Exception e) {
            if (!StringUtils.isEmpty(filePath)) {
                clientWrapper.deleteFile(filePath.split("#")[0]);
            }
            msg.setCode(BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
            msg.setDescription("导入失败");
            return msg;
        }
    }

    @SuppressWarnings("deprecation")
    public void updateFstatusflag(List<String> idList, int fstatusflag) {
        try (SessionFactory factory = new SessionFactory();) {
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            lhsMapper.updateFstatusflag(idList, fstatusflag);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    @SuppressWarnings({"rawtypes", "deprecation"})
    @Override
    public MessageBean<?> saveDraft(List<LocalHazardSource> lhsList, StaffBean user) {
        MessageBean<List> msg = new MessageBean<List>();
        SessionFactory factory = new SessionFactory();
        try {
            Map checkMap = addCheck(lhsList);
            int code = (int) checkMap.get("code");
            String description = (String) checkMap.get("description");
            if (code != 0) {
                msg.setCode(code);
                msg.setDescription(description);
                factory.close(false);
                return msg;
            }
            List<String> idList = new ArrayList<String>();
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            Date date = new Date();
            for (LocalHazardSource lhs : lhsList) {
                List<LocalRisk> lrList = lhs.getRisks();
                if (lhs.getState() == null) {
                    lhs.setState(1);
                }
                if (lhs.getFitAllBusiness()) {
                    lhs.setBusinessTypeId(null);
                }
                lhs.setAddTime(date);
                lhs.setAddUser(user.getCode());
                lhs.setAddUserName(user.getName());
                lhs.setUpdateTime(date);
                lhs.setUpdateUser(user.getCode());
                lhs.setUpdateUserName(user.getName());
                lhs.setFstatusflag(0); //待提交状态
                lhs.setState(1);//草稿状态
                String id = lhs.getId();
                if (lhs.getTemplateCode() == null) {
                    lhs.setExclusive(0);
                } else {
                    lhs.setExclusive(1);
                }
                if (StringUtils.isEmpty(id)) {
                    //新增
                    id = DefaultIdGenerator.getInstance().generateLongId();
                    lhs.setId(id);
                    for (LocalRisk lr : lrList) {
                        lr.setId(DefaultIdGenerator.getInstance().generateLongId());
                        lr.setAddTime(date);
                        lr.setAddUser(user.getCode());
                        lr.setLocalHazardId(id);
                    }
                    lhsMapper.insert("local_hazard_source_history", lhs);
                    lrMapper.batchInsert("local_risk_history", lrList);
                } else {
                    lrMapper.deleteBySourceId("local_risk_history", id);
                    for (LocalRisk lr : lrList) {
                        lr.setId(DefaultIdGenerator.getInstance().generateLongId());
                        lr.setAddTime(date);
                        lr.setAddUser(user.getCode());
                        lr.setLocalHazardId(id);
                    }
                    lhsMapper.update("local_hazard_source_history", lhs);
                    lrMapper.batchInsert("local_risk_history", lrList);
                }
                idList.add(id);
            }
            factory.close();
            msg.setCode(0);
            msg.setDescription("保存成功");
            msg.setData(idList);
        } catch (Exception e) {
            if (null != factory)
                factory.close(false);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public MessageBean<?> submit(List<LocalHazardSource> lhsList, StaffBean user, String title, String note, String approvalCode) {
        MessageBean<?> msg = saveDraft(lhsList, user);
        try {
            List<String> idList = new ArrayList<String>();
            if (msg.getData() != null) {
                idList = (List<String>) msg.getData();
            } else {
                return msg;
            }
            String corpCode = lhsList.get(0).getCorpCode();
            String tk = addTemplateKey;
            //启动流程
            Audit audit = new Audit(title, note, user.getName(), new Date());
            audit.setId(DefaultIdGenerator.getInstance().generateLongId());
            audit.setTitle(title);
            audit.setDescription(note);
            audit.setInitiatorCode(user.getCode());
            audit.setTarget(LocalHazardSource.class.getName());
            audit.setTemplateKey(tk);
            audit.setOperation(1); //编辑
            audit.setState(1);
            audit.setFlowType(1);
            audit.setFlowName(Immutable.ADD_LOCAL_HAZARD_SOURCE);
            audit.setBusinessIds(new Gson().toJson(idList));
            audit.setCorpCode(corpCode);
            audit.setInitiatorAccount(user.getUserid());
            audit.setSetCode(riskDangerSetCode);

            Map map = new HashMap<>();
            map.put("approvalCode", approvalCode);

            if (!flowManagement.initFlow(user, audit, map)) {
                delete(idList);
                msg.setCode(BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
            }
            updateFstatusflag(idList, 1);  //审批中
            return msg;
        } catch (Exception e) {
            return msg;
        }
    }

    @SuppressWarnings("deprecation")
    public void delete(List<String> idList) {
        try (SessionFactory factory = new SessionFactory();) {
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            lhsMapper.deleteByIdList("local_hazard_source_history", idList);
            for (String str : idList) {
                lrMapper.deleteBySourceId("local_risk_history", str);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    @SuppressWarnings("deprecation")
    public List<LocalHazardSource> queryList(SourceQueryBean queryBean) {
        try (SessionFactory factory = new SessionFactory()) {

            List<LocalHazardSource> list = factory.getMapper(LocalHazardSourceMapper.class).list(queryBean);
            Map<String, String> corpMap = corpManagementService.getCodeNameMap();
            for (LocalHazardSource lhs : list) {
                List<LocalRisk> lrList = factory.getMapper(LocalRiskMapper.class).queryBySourceId("local_risk", lhs.getId());
                Integer temp = 0;
                String levelName = "";
                if ("LS".equals(lhs.getIdentificationType())) {
                    for (LocalRisk lr : lrList) {
                        RiskLevelDesc levelDesc = match(lr.getRiskLevel());
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        levelDesc = match(lr.getResidueLevel());
                        lr.setResidueLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                } else {
                    for (LocalRisk lr : lrList) {
                        RiskLECDesc levelDesc = matchRiskLECDesc(new BigDecimal(lr.getRiskLevel()));
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                }

                lhs.setRisks(lrList);
                if (temp != 0) {
                    lhs.setRiskLevel(temp);
                    lhs.setRiskLevelName(levelName);
                }
                String corpName = corpMap.get(lhs.getCorpCode());
                if (corpName == null) {
                    CorpBean corpBean = factory.getMapper(CorpManagementMapper.class).get(lhs.getCorpCode());
                    if (corpBean != null) {
                        corpName = corpBean.getCorpName();
                        corpMap.put(lhs.getCorpCode(), corpName);
                    }
                }
                lhs.setCorpName(corpName);
            }
            return list;
        }
    }

    private static Map<RiskLevelDesc, List<Integer>> levelMap = new HashMap<>();

    static {
        levelMap.put(RiskLevelDesc.Minor, Arrays.asList(1, 2, 3, 4));
        levelMap.put(RiskLevelDesc.Ordinary, Arrays.asList(5, 6, 8, 9));
        levelMap.put(RiskLevelDesc.Serious, Arrays.asList(10, 12, 15, 16));
        levelMap.put(RiskLevelDesc.Important, Arrays.asList(20, 25));
    }

    private RiskLevelDesc match(Integer riskLevel) {
        for (Map.Entry<RiskLevelDesc, List<Integer>> entry : levelMap.entrySet()) {
            RiskLevelDesc key = entry.getKey();
            List<Integer> value = entry.getValue();
            if (value.contains(riskLevel)) {
                return key;
            }
        }
        return null;
    }

    private RiskLECDesc matchRiskLECDesc(BigDecimal riskLevel) {
        if (riskLevel.compareTo(BigDecimal.ZERO) == 1 && riskLevel.compareTo(new BigDecimal(20)) == -1) {
            return RiskLECDesc.LOW;
        } else if (riskLevel.compareTo(new BigDecimal(70)) == -1) {
            return RiskLECDesc.Minor;
        } else if (riskLevel.compareTo(new BigDecimal(160)) == -1) {
            return RiskLECDesc.Ordinary;
        } else if (riskLevel.compareTo(new BigDecimal(320)) == -1) {
            return RiskLECDesc.Serious;
        } else if (riskLevel.compareTo(new BigDecimal(320)) == 1) {
            return RiskLECDesc.Important;
        } else {
            return null;
        }
    }


    @SuppressWarnings({"rawtypes", "unchecked"})
    private Map addCheck(List<LocalHazardSource> lhsList) {
        Map map = new HashMap();
        for (LocalHazardSource lhs : lhsList) {
            if (null == lhs) {
                map.put("code", 32002);
                map.put("description", "未填写危险源信息无法保存");
                return map;
            }
            List<LocalRisk> lrList = lhs.getRisks();
            if (null == lrList) {
                map.put("code", 32002);
                map.put("description", "未填写危险源的风险项信息无法保存");
                return map;
            }
            //校验危险源的字段
            if (StringUtils.isEmpty(lhs.getName())) {
                map.put("code", 32002);
                map.put("description", "危险源名称不能为空");
                return map;
            }
            if (!lhs.getFitAllBusiness()) {
                if (StringUtils.isEmpty(lhs.getBusinessTypeId())) {
                    map.put("code", 22001);
                    map.put("description", "非通用，危险源业态不能为空");
                    return map;
                }
            }
            if (StringUtils.isEmpty(lhs.getHazardTypeId())) {
                map.put("code", 32002);
                map.put("description", "危险源类型不能为空");
                return map;
            }
            if (StringUtils.isEmpty(lhs.getIdentificationType())) {
                map.put("code", 32002);
                map.put("description", "危险源辨识方式不能为空");
                return map;
            }
            if (!"LS".equals(lhs.getIdentificationType()) && !"LEC".equals(lhs.getIdentificationType())) {
                map.put("code", 32002);
                map.put("description", "危险源辨识方式值不合法");
                return map;
            }

            int riskLevel = 0;
            //校验风险的字段
            for (LocalRisk lr : lrList) {
                if (StringUtils.isEmpty(lr.getRiskInfo())) {
                    map.put("code", 32002);
                    map.put("description", "风险列表中存在风险描述为空");
                    return map;
                }

                if (StringUtils.isEmpty(lr.getRiskReason())) {
                    map.put("code", 32002);
                    map.put("description", "风险列表中存在风险原因描述为空");
                    return map;
                }
                if (StringUtils.isEmpty(lr.getAccidentTypeId())) {
                    map.put("code", 32002);
                    map.put("description", "风险列表中存在风险事故类型为空");
                    return map;
                }

                if ("LS".equals(lhs.getIdentificationType())) {
                    ///以下是LS的判断方式
                    if (null == lr.getPossibility()) {
                        map.put("code", 32002);
                        map.put("description", "风险列表中存在风险可能性为空");
                        return map;
                    }
                    if (null == lr.getSeverity()) {
                        map.put("code", 32002);
                        map.put("description", "风险列表中存在风险项严重性为空");
                        return map;
                    }

                    //计算风险等级
                    lr.setRiskLevel(lr.getPossibility() * lr.getSeverity());
                    if (riskLevel < lr.getRiskLevel()) {
                        riskLevel = lr.getRiskLevel();
                    }

                    RiskLevelDesc levelDesc = match(lr.getRiskLevel());
                    lr.setControlLevel(levelDesc != null ? levelDesc.getControlDesc() : "");

                    if (lr.getResiduePossibility() != null && lr.getResidueSeverity() != null) {
                        //残余风险等级
                        lr.setResidueLevel(lr.getResiduePossibility() * lr.getResidueSeverity());
                        levelDesc = match(lr.getResidueLevel());
                        lr.setResidueControlLevel(levelDesc != null ? levelDesc.getControlDesc() : "");
                    }
                } else {
                    if (null == lr.getOccurencePossibility()) {
                        map.put("code", 32002);
                        map.put("description", "风险列表中发生事故可能性为空");
                        return map;
                    }

                    BigDecimal temp = lr.getOccurencePossibility().multiply(lr.getFrequently());
                    BigDecimal result = temp.multiply(lr.getConsequence());
                    lr.setRiskLevel(result.intValue());
                    if (riskLevel < lr.getRiskLevel()) {
                        riskLevel = lr.getRiskLevel();
                    }
                    RiskLECDesc riskLECDesc = matchRiskLECDesc(result);
                    lr.setControlLevel(riskLECDesc != null ? riskLECDesc.getControlDesc() : "");
                }
            }
            lhs.setRiskLevel(riskLevel);
        }
        map.put("code", 0);
        map.put("description", "校验成功");
        return map;
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    @Override
    public MessageBean<?> getHistoryList(String code) {
        MessageBean<List> msg = MessageBean.create(0, "success", List.class);
        try (SessionFactory factory = new SessionFactory()) {
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            List<LocalHazardSource> list = lhsMapper.queryHstory(code);
            Map<String, String> corpMap = corpManagementService.getCodeNameMap();
            for (LocalHazardSource lhs : list) {
                List<LocalRisk> lrList = lrMapper.queryBySourceId("local_risk_history", lhs.getId());
                Integer temp = 0;
                String levelName = "";
                if ("LS".equals(lhs.getIdentificationType())) {
                    for (LocalRisk lr : lrList) {
                        RiskLevelDesc levelDesc = match(lr.getRiskLevel());
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        levelDesc = match(lr.getResidueLevel());
                        lr.setResidueLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                } else {
                    for (LocalRisk lr : lrList) {
                        RiskLECDesc levelDesc = matchRiskLECDesc(new BigDecimal(lhs.getRiskLevel()));
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                }

                lhs.setRisks(lrList);
                if (temp != 0) {
                    lhs.setRiskLevel(temp);
                    lhs.setRiskLevelName(levelName);
                }
                String corpName = corpMap.get(lhs.getCorpCode());
                if (corpName == null) {
                    CorpBean corpBean = factory.getMapper(CorpManagementMapper.class).get(lhs.getCorpCode());
                    if (corpBean != null) {
                        corpName = corpBean.getCorpName();
                        corpMap.put(lhs.getCorpCode(), corpName);
                    }
                }
                lhs.setCorpName(corpName);
            }
            msg.setData(list);
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    @Override
    public MessageBean<?> getProcessData(String ids) {
        MessageBean<List> msg = MessageBean.create(0, "success", List.class);
        try (SessionFactory factory = new SessionFactory()) {
            List<String> idList = JSONObject.parseArray(ids, String.class);
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            List<LocalHazardSource> list = lhsMapper.queryByIdList("local_hazard_source_history", idList);
            Map<String, String> corpMap = corpManagementService.getCodeNameMap();
            for (LocalHazardSource lhs : list) {
                List<LocalRisk> risks = lrMapper.queryBySourceId("local_risk_history", lhs.getId());
                Integer temp = 0;
                String levelName = "";
                if ("LS".equals(lhs.getIdentificationType())) {
                    for (LocalRisk lr : risks) {
                        RiskLevelDesc levelDesc = match(lr.getRiskLevel());
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        levelDesc = match(lr.getResidueLevel());
                        lr.setResidueLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                } else {
                    for (LocalRisk lr : risks) {
                        RiskLECDesc levelDesc = matchRiskLECDesc(new BigDecimal(lhs.getRiskLevel()));
                        lr.setRiskLevelName(levelDesc != null ? levelDesc.getName() : "");
                        Integer level = lr.getRiskLevel() == null ? 0 : lr.getRiskLevel();
                        if (level > temp) {
                            temp = level;
                            levelName = lr.getRiskLevelName();
                        }
                    }
                }
                lhs.setRisks(risks);
                if (temp != 0) {
                    lhs.setRiskLevel(temp);
                    lhs.setRiskLevelName(levelName);
                }
                String corpName = corpMap.get(lhs.getCorpCode());
                if (corpName == null) {
                    CorpBean corpBean = factory.getMapper(CorpManagementMapper.class).get(lhs.getCorpCode());
                    if (corpBean != null) {
                        corpName = corpBean.getCorpName();
                        corpMap.put(lhs.getCorpCode(), corpName);
                    }
                }
                lhs.setCorpName(corpName);
            }
            msg.setData(list);
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<?> deleteDraft(String id) {
        MessageBean<?> msg = MessageBean.create(0, "success", void.class);
        SessionFactory factory = new SessionFactory();
        try {
            LocalHazardSourceMapper lhsMapper = factory.getMapper(LocalHazardSourceMapper.class);
            LocalRiskMapper lrMapper = factory.getMapper(LocalRiskMapper.class);
            lhsMapper.deleteDraft(id);
            lrMapper.deleteDraft(id);
            factory.close();
        } catch (Exception e) {
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
        return msg;
    }

    @Override
    public MessageBean<?> exportList(SourceQueryBean queryBean) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, DataBean.class);
        queryBean.setStart(null);
        queryBean.setEnd(null);
        if (null != queryBean.getRiskLevelStart()) {
            if (queryBean.getRiskLevelStart() == 1) {
                queryBean.setLevelStart(1);
            } else if (queryBean.getRiskLevelStart() == 5) {
                queryBean.setLevelStart(70);
            } else if (queryBean.getRiskLevelStart() == 10) {
                queryBean.setLevelStart(160);
            } else if (queryBean.getRiskLevelStart() == 17) {
                queryBean.setLevelStart(320);
            }
        }
        if (null != queryBean.getRiskLevelEnd()) {
            if (queryBean.getRiskLevelEnd() == 4) {
                queryBean.setLevelEnd(70);
            } else if (queryBean.getRiskLevelEnd() == 9) {
                queryBean.setLevelEnd(160);
            } else if (queryBean.getRiskLevelEnd() == 16) {
                queryBean.setLevelEnd(320);
            } else if (queryBean.getRiskLevelEnd() == 25) {
                queryBean.setLevelEnd(10000);
            }
        }
        queryBean.setTableName("local_hazard_source");
        DataBean data = new DataBean();
        data.setList(queryList(queryBean));
        msg.setData(data);
        return msg;
    }
}
